home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
clock.aqm
/
clock.asm
Wrap
Assembly Source File
|
1985-01-28
|
17KB
|
683 lines
PAGE 60,132
TITLE Replacement system clock driver for AST board
COMMENT*This is an installable device driver to access the battery
driven clock on AST combo board & I/O port 2C0+1F
AUTHOR: David K.Broadwell -- July 1983
Copied from BYTE 1/84 by Fred A. Strobl -- Jan. 84
REVISED TO ELIMINATE 12K OF WASTED MEMORY - ADDED SET DAY OF WEEK
TO INSTALL: ADD TO CONFIG.SYS :
DEVICE=CLOCK.COM
Daniel M. O'Brien (dmo) - 1/28/84
Set the bios time counter (tics) from clock chip for those applications
that read the bios counter directly (via INT 1A)!
*
CSEG SEGMENT PARA PUBLIC 'CODE'
;
; M A C R O S
;
STATUS MACRO STATE,ERR,RC
ifidn <STATE>,<DONE>
OR ES:WORD PTR SRH_STA_FLD[BX],0100H
endif
ifidn <STATE>,<BUSY>
OR ES:WORD PTR SRH_STA_FLD[BX],0200H
endif
ifidn <ERR>,<ERROR>
OR ES:WORD PTR SRH_STA_FLD[BX],1000H
endif
ifnb <RC>
OR ES:WORD PTR SRH_STA_FLD[BX],RC
endif
endm
;
; E Q U A T E S
;
SRH EQU 0 ;STATIC REQUEST HEADER START
SRH_LEN EQU 13 ; " " " LENGTH
SRH_LEN_FLD EQU SRH ; " " " " FIELD
SRH_UCD_FLD EQU SRH+1 ;SRH UNIT CODE FIELD
SRH_CCD_FLD EQU SRH+2 ;SRH COMMAND CODE FIELD
SRH_STA_FLD EQU SRH+3 ;SRH STATUS FIELD
SRH_RES_FLD EQU SRH+5 ;SRH RESERVED AREA FIELD
;
; INPUT OR OUTPUT
;
BUF EQU 14 ;OFFSET INTO THE REQ BLOCK OF DATA (BUFFER) TRANSFER ADDRESS
BUF_LEN EQU 4 ;BUF LENGTH
;
; INIT
;
BR_ADDR_0 EQU 14 ;CHARACTER DEVICE USUALLY ONLY SETS
BR_ADDR_1 EQU BR_ADDR_0+2 ; ENDING ADDRESS AND RETURNS
BR_ADDR_LEN EQU 4
;
; OFFSETS FROM CLOCK BASE PORT
;
MON EQU 7 ;OFFSET OF MONTH
DAYY EQU 6 ; " " DAY OF MONTH
VALID EQU 8 ; " " VALIDATION CODE IN RAM
MON_CHECK EQU 9 ; " " MONTH CHECKER IN RAM
SWITCH EQU 0BH ; " " LEAP BK RAM ON CHIP
COUNTER_RESET EQU 12H ; " " OF RESET(RAM RESET IS ONE UP AT 13H)
STATUS_BIT EQU 14H ;OFFSET TO STATUS BYTE--80=UNRELIABLE READ, 00 = OK
;
; MISC
;
DAYS_YR EQU 365 ;DAYS PER USUAL YEAR
YES_CODE EQU 02 ;YES CODE FOR LEAP YEAR BOOKEEPING
NO_CODE EQU 01 ;NO CODE FOR SAME
VALID_CODE EQU 10H ;VALIDATE CHIP CODE
DAYS_FEB29 EQU 60 ;DAYS UP TO AND INCLUDING FEB 29TH (FOR LEAP YEARS ONLY)
;
; S T R U C T U R E S
;
CLOCK EQU 2C0H ;BASE PORT
;
; ■■ 58157A CLOCK-CALENDAR CHIP I/O ADDRESSES
;
CLOCK_PORTS STRUC
TEN_THOUS DB ? ;1/10000s of seconds(who cares?)
HUNDS DB ? ;hundredth
SECS DB ? ;seconds
MINS DB ? ;minutes
HRS DB ? ;hours
WEK_DAY DB ? ;day of week
DAY DB ? ;day of month
MO DB ? ;month
VERIFY DB ? ;chip RAM used to check chip config at initialization
MON_CHK DB ? ;RAM with month of last chip access
YR DB ? ;year-1980 (port 2C0 + 0A)
LEAP_BK DB ? ;used for leap year bookeeping (set to 02 when all is cool)
;
CLOCK_PORTS ENDS
CLK PROC FAR
ASSUME CS:CSEG,ES:CSEG,DS:CSEG
BEGIN:
;
; S P E C I A L D E V I C E H E A D E R
;
NEXT_DEV DD -1 ;POINTER TO NEXT DEVICE
ATTRIBUTE DW 8008H ;CLOCK DEVICE (NEW STD.)
STRATEGY DW DEV_STRATEGY ;POINTER TO DEVICE STRATEGY
INTERRUPT DW DEV_INT ;POINTER TO INTERRUPT HANDLER
DEV_NAME DB 'CLOCK$' ;DEVICE NAME
DB 2 DUP(?) ;FILLER
;
RH_OFF DW ? ;REQUEST HEADER OFFSET
RH_SEG DW ? ;R HDR SEGMENT
USER_BUF DD ? ;USER TRANSFER ADDRESS (BUFFER)
;
; FUNCTION TABLE
;
FUNTAB LABEL BYTE
DW INIT ;INITIALIZATION -USED FIRST TIME DEVICE IS CALLED
DW MEDIA_CHECK ;(BLOCK ONLY) -NOT USED
DW BUILD_BPB ; " " -NOT USED
DW IOCTL_IN ;IOCTL INPUT -NOT USED
DW INPUT ;INPUT(READ) = GET THE TIME/DATE
DW ND_INPUT ;NON-DESTRUCTIVE INPUT (CHAR ONLY) -NOT USED
DW IN_STAT ;CHAR ONLY -NOT USED
DW IN_FLUSH ;C.O -NOT USED
DW OUTPUT ;OUTPUT(WRITE) = SET TIME/DATE
DW OUT_VERIFY ;OUTPUT W/VERIFY-NOT USED
DW OUT_STAT ;C.O. -NOT USED
DW OUT_FLUSH ;C.O. -NOT USED
DW IOCTL_OUT ;IOCTL OUTPUT -NOT USED
;
; LOCAL DATA BLOCK IN DOS 2.0 FORMAT
;
CLK_TBL LABEL BYTE
DW ? ;DAYS SINCE 1-1-80
DB ? ;MINS
DB ? ;HOURS
DB ? ;1/100THS SEC
DB ? ;SECONDS
;
; MONTH TABLE
;
MON_TBL LABEL BYTE
DW 0 ;JAN
DW 31 ;FEB
DW 59 ;MAR
DW 90 ;APR
DW 120 ;MAY
DW 151 ;JUNE
DW 181 ;JULY
DW 212 ;AUG
DW 243 ;SEPT
DW 273 ;OCT
DW 304 ;NOV
DW 334 ;334 DAYS UP TO DEC 1
DW 365 ;DAYS UP TO JAN 1, NEXT YR
;
; TABLE OF CURRENT CLOCK VALUES
;
UHR CLOCK_PORTS <> ;Allocates to predefined STRUC
;
; VARIABLES FOR TRACKING THOSE PESKY LEAP YEARS
;
LEAP_STAT DB 0 ;10H MEANS CURRENT YEAR IS A LEAP
NUM_LEAPS DB ? ;NUMBER OF LEAP YEARS SINCE 1980
;
; L O C A L P R O C E D U R E S
;
IN_SAVE PROC NEAR
MOV AX,ES:WORD PTR BUF[BX] ;SAVE CALLER'S BUFFER ADD
MOV CS:USER_BUF,AX
MOV AX,ES:WORD PTR BUF+2[BX]
MOV CS:USER_BUF+2,AX
RET
IN_SAVE ENDP
READ_CLOCK PROC NEAR
call read_chip ;read time off chip into uhr structure dmo
;
; Routine to massage data for transfer to DOS
;
CALL NEW_YEAR ;CHECK TO SEE IF IT'S A NEW YEAR
CALL DAYS ;NUMBER OF DAYS SINCE 1/1/80
CALL TIME ;CURRENT TIME IN HEX
MOV ES,CS:USER_BUF+2 ;SET DESTINATION (ES:DI) TO POINT TO
MOV DI,CS:USER_BUF ; CALLER'S BUFFER
PUSH CS
POP DS ;ESTABLISH SOURCE
;SI ALREADY HAS CLK_TBL ADDRESS
MOV CX,6 ;6 BYTES
REP MOVSB ;SEND INFO TO BUFFER FOR "READ"
RET
READ_CLOCK ENDP
;
; read time off chip into uhr data structure - made a subroutine by -------> dmo
;
read_chip proc near
PUSH CS ;SET UP TO READ CHIP AND STORE IT
POP ES
RETRY: LEA DI,UHR
CLD
SUB AX,AX
MOV CX,12
MOV DX,CLOCK ;ADDRESS OF CHIP BASE PORT
LOADIT: IN AL,DX
INC DX
PUSH CX
CALL DEC_HEX ;CONVERT BCD TO HEX
STOSB
POP CX ;RESTORE COUNTER
LOOP LOADIT
;
; Check for counter rollover during read (STATUS BYTE = 80H)
;
MOV DX,CLOCK+STATUS_BIT
IN AL,DX
TEST AL,AL
JNZ RETRY
ret ; dmo
read_chip endp ; dmo
DAYS PROC NEAR
SUB AX,AX
MOV AL,UHR.YR ;YEAR-1980
MOV BX,DAYS_YR
MUL BX ;MUL FOR DAYS
SUB CX,CX
MOV CL,UHR.MO ;LOAD MONTH IN CL AND ...
CALL DAYS_MONTH ; CALL ROUTINE TO ACCESS MONTH TABLE
ADD AX,WORD PTR[BX] ;ADD THAT YEAR'S DAYS (XCEPT CUR MO)
XOR BH,BH
MOV BL,UHR.DAY ;GET DAY OF MONTH
ADD AX,BX ;DAYS SINCE 1-1-80,EXCEPT LEAP DAYS
PUSH AX
MOV AL,UHR.YR
CALL LEAP_CHK ;CHECK THOSE TOO
POP AX
SUB DX,DX
MOV DL,NUM_LEAPS
ADD AX,DX ;ADD IN OLD LEAP DAYS
TEST LEAP_STAT,10H ;CURRENT YEAR A LEAP?
JZ D1 ;JUMP ON NO
CALL LEAP_ADJ ;YES -GO FIX THINGS
D1: LEA SI,CLK_TBL
MOV WORD PTR [SI],AX ;SAVE RESULT
RET
DAYS ENDP
;
; GET HRS,MIN,SEC AND 1/100THS SEC
;
TIME PROC NEAR
LEA DI,CLK_TBL[2] ;SET UP TO LOAD DATA LOCALLY IN RIGHT ORDER
XOR AH,AH
MOV AL,UHR.MINS
STOSB
MOV AL,UHR.HRS
STOSB
MOV AL,UHR.HUNDS
STOSB
MOV AL,UHR.SECS
STOSB
RET
TIME ENDP
DAYS_MONTH PROC NEAR ;MONTH ARRIVES HERE IN CL
SUB CL,1 ;ADJUST TO GET THE CORRECT OFFSET INTO
ROL CL,1 ; THE TABLE
LEA BX,MON_TBL ;GET ADDRSS OF MONTH TABLE
ADD BX,CX ;NOW WORD PTR[BX] HAS NUM OF DAYS UP TO THE CURRENT MO
RET
DAYS_MONTH ENDP
NEW_YEAR PROC NEAR ;CHECK FOR A "NEW YEAR" AND/OR UPDATE MON_CHK
MOV AL,UHR.MO ;CURRENT MONTH
CMP AL,UHR.MON_CHK ;STORED ON CHIP - THE LAST "MONTH" WE READ IT
JL NEW ;1<12 SO IT'S A NEW YEAR
JG UPDATE ; IT'S A NEW MONTH
RET ;SAME OLD MONTH - GO BACK
NEW: INC UHR.YR ;LAST YEAR - 1980,+1
MOV AL,UHR.YR
CALL HEX_DEC ;MAKE IT BCD LIKE EVERYTHING ELSE
MOV DX,CLOCK+10 ;RAM ADD FOR YEAR
OUT DX,AL
UPDATE: MOV AL,UHR.MO ;UPDATE MON_CHK ON RAM
MOV DX,CLOCK+9
OUT DX,AL
RET
NEW_YEAR ENDP
DEC_HEX PROC NEAR ;CONVERTS SMALL PACKED BCD TO HEX
PUSH AX
MOV CL,4
SHR AL,CL
POP BX
MOV BH,10
MUL BH
AND BL,0FH
ADD AL,BL
RET
DEC_HEX ENDP
HEX_DEC PROC NEAR ;CONVERTS HEX NUMBERS UP TO 63H(=99) TO BCD
SUB AH,AH ; HEX NUMBER PASSED IN AL
MOV BL,10
DIV BL
MOV CL,04
SHL AL,CL
XCHG AL,AH
OR AL,AH ;BCD IN AL
RET
HEX_DEC ENDP
LEAP_CHK PROC NEAR ;SETS NUMBER OF LEAP YEARS PAST &
STATUS BYTE
CMP AL,0 ;IS IT 1980 ?
JE L2 ;YES - FORGET THE REST
XOR AH,AH ;PUT YEAR-1980 IN AL BEFORE CALL
DEC AL
MOV BL,4
DIV BL
CMP AH,3
JNE NOT_LEAP
OR LEAP_STAT,10H ;SET LEAP STATUS BIT ON(CURR YR IS A LEAP)
JMP L1
NOT_LEAP:
MOV LEAP_STAT,0
L1: MOV NUM_LEAPS,AL ;NUMBER OF LEAP DAYS SINCE 1980
L2: RET
LEAP_CHK ENDP
LEAP_ADJ PROC NEAR ;ADJUSTS CHIP AND/OR DAYS COUNT DURING LEAPS
CMP UHR.LEAP_BK,YES_CODE ;HAVE WE ALREADY DONE THE BOOKEEPING?
JE DONE1 ;JUMP ON YES
MOV BH,UHR.MO ;IS IT BEFORE/AT FEB 29 -- (CHIP THINKS IT'S 3/1)
MOV BL,UHR.DAY
CMP BX,0301H
JLE DONE2 ;YES - JUMP
;
;BACK UP A DAY AND RECORD IT IN RAM:
;
CMP UHR.DAY,1 ;IS IT THE 1ST OF A MONTH?
JE FOOEY ;JUMP ON YES AND WHAT A PAIN
PUSH AX ;NO -JUST BACK UP ONE DAY AND SET LEAP_BK
XOR AH,AH
MOV AL,UHR.DAY
DEC AL
BAK: MOV DX,CLOCK+DAYY ;CHIP PORT
OUT DX,AL
MOV AL,YES_CODE
MOV DX,CLOCK+SWITCH
OUT DX,AL ;SET LEAP_BK ON RAM SO WE WON'T HAVE TO DO THIS AGAIN
POP AX
JMP DONE2
FOOEY: SUB CX,CX ;BACK UP DAY AND MONTH BOTH
MOV CL,UHR.MO
PUSH AX
MOV AX,CX
MOV DX,CLOCK+MON
DEC AL
OUT DX,AL
ADD DX,2 ;RESET MONTH VERIFY ON RAM TOO
OUT DX,AL
CALL DAYS_MONTH
MOV AX,WORD PTR[BX] ;NOW FIND OUT HOW MANY DAYS LAST MONTH HAD
SUB AX,WORD PTR[BX]-2 ;YESTERDAY NOW IN AL
JMP BAK ;FINISH UP
DONE1: INC AX ;ALL THE REST OF YR ADD ONE MO' DAY
DONE2: RET
LEAP_ADJ ENDP
SET_CLOCK PROC NEAR ;GETS DATA FROM DOS, CRUNCHES IT & SETS CHIP
MOV DS,CS:USER_BUF+2 ;SET SOURCE TO CALLER'S(DOS)BUFFER BLK ADR
MOV SI,CS:USER_BUF
PUSH CS
POP ES
LEA DI,CLK_TBL
MOV CX,6 ;SET UP TO MOVE DATA LOCALLY
CLD
REP MOVSB ;DO IT
;
; CALCULATE AND LOAD LOCAL CLOCK CHIP TABLE (STRUCTURE)
;
PUSH CS
POP DS ;ESTABLISH DS AS THIS SEG
CALL LOAD_TICKS ;DO TIME PART(EASY)
CALL UNSCRAM ;DAYS TO YR-MO-DAY
;
; SET CHIP
;
SUB AX,AX
MOV CX,12
MOV DX,CLOCK ;CHIP BASE PORT ADDRESS
LEA SI,UHR ;SOURCE=CHIP TABLE WE'VE SET UP
DMPIT: LODSB ;MOVE DATA TO AL
PUSH CX ;NEXT ROUTINE TRASHES COUNTER
CALL HEX_DEC ;CHANGE TO BCD
OUT DX,AL ;"WRITE" TO CHIP
INC DX ;NEXT PORT
POP CX
LOOP DMPIT ;LOOP 'TIL DONE
RET
SET_CLOCK ENDP
LOAD_TICKS PROC NEAR ;LOAD TIME INTO CHIP STRUCTURE FORMAT
LEA SI,CLK_TBL[2]
XOR AH,AH
LODSB
MOV UHR.MINS,AL
LODSB
MOV UHR.HRS,AL
LODSB
MOV UHR.HUNDS,AL
LODSB
MOV UHR.SECS,AL
RET
LOAD_TICKS ENDP
UNSCRAM PROC NEAR ;DAYS SINCE 1-1-80 TO MM/DD/YY
LEA BP,CLK_TBL
MOV AX,WORD PTR CS:[BP] ;FIRST WORD IN CLK_TBL
CMP AX,0 ;IF IT'S 1-1-80, TAKE SHORT CUT
JE U4
;ADDED DAY OF WEEK ROUTINE *** FAS
PUSH AX ; ***FAS
ADD AX,3 ;1-1-1980=TUESDAY(DAY3) ***FAS
CWD ; ***FAS
MOV BX,7 ;DAYS IN WEEK ***FAS
DIV BX ; ***FAS
MOV UHR.WEK_DAY,DL ;STORE ***FAS
POP AX ;CONTINUE ***FAS
MOV BX,DAYS_YR
CWD ;BLANK OUT DX FOR DIVIDE
DIV BX ;YRS GOTO AL,DAYS LEFT TO DX
MOV UHR.YR,AL ;SAVE YRS SINCE 1980
;NOW CHECK WHETHER LEAP DAYS OR END OF
CALL LEAP_CHK ; YEAR HAVE MADE IT LOOK LIKE A NEW YR
SUB CX,CX
MOV CL,NUM_LEAPS
CMP DX,CX
JG OK ;IF REMAINDER DAYS<LEAP DAYS, FIX IT
ADD DX,DAYS_YR
DEC UHR.YR ;ALL FILLED NOW
MOV AL,UHR.YR ;REDO LEAP VARIABLES
CALL LEAP_CHK
OK: XOR BX,BX
MOV BL,NUM_LEAPS
SUB DX,BX ;CORRECT FOR LEAPS
TEST LEAP_STAT,10H ;CURRENT YEAR A LEAP ?
JZ U0 ;JUMP ON NO
CMP DX,DAYS_FEB29 ;AT/BEFORE FEB 29?
JLE U0 ;YES- JUMP
MOV UHR.LEAP_BK,YES_CODE ;SET RAM SWITCH TO 'YES'
DEC DX ;NO - TAKE OUT THAT EXTRA DAY
JMP U1
U0: MOV UHR.LEAP_BK,NO_CODE ;SET RAM TO 'NO'
U1: MOV BX,26
LEA DI,MON_TBL
U2: SUB BX,2
CMP WORD PTR [DI][BX],DX
JGE U2 ;FIND RIGHT MONTH IN TABLE
SUB DX,WORD PTR [DI][BX] ;DAYS INTO MONTH LEFT IN DX
ROR BL,1
INC BL
U3: MOV UHR.DAY,DL
MOV UHR.MON_CHK,BL ;SET UP MONTH VERIFY IN RAM TOO
MOV UHR.MO,BL
RET
U4: MOV DL,0 ;SET UP FOR 1-1-80 "in the beginning..."
MOV BL,1
MOV UHR.YR,0
JMP U3
UNSCRAM ENDP
; dmo
; setup bios ram counter - tics (18.2/sec) since midnight dmo
; dmo
; called whenever chip is changed and during initialization dmo
; dmo
; dmo
set_bios_counter proc near
push cs
pop ds ;setup data addressability
xor ah,ah
mov al,uhr.hrs ;get current hours
mov cx,60 ;convert to minutes
mul cx
mov bx,ax ;save for total
xor ah,ah
mov al,uhr.mins ;get current minutes
add ax,bx ;total minutes
mov cx,1092 ;convert minutes to tics - tech ref a-4
mul cx
push dx ;save current total tics - high word
push ax ; - low word
xor ah,ah
mov al,uhr.secs ;get current seconds
mov cx,18 ;convert secs to tics
mul cx
pop cx ;get previous total tics - low word
add ax,cx ;sum tics
pop cx ;get previous total ticss - high word
adc dx,cx ;sum tics
mov cx,dx ;get tics into proper regs
mov dx,ax
mov ah,1 ;flag to set clock
int 1ah ;set clock via bios - tech ref a-77
ret
set_bios_counter endp ; dmo
;
; D E V I C E S T R A T E G Y
;
DEV_STRATEGY:
MOV CS:RH_SEG,ES ;SAVE SEGMENT OF REQUEST HEADER PTR
MOV CS:RH_OFF,BX ;SAVE OFFSET OF SAME
RET
;
; D E V I C E I N T E R R U P T H A N D L E R
;
DEV_INT:
;PRESERVE MACHINE STATE
CLD
PUSH DS
PUSH ES
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
;
;BRANCH ACCORDING TO THE FUNCTION PASSED
;
MOV BX,CS:RH_OFF ;GET REQUEST BLOCK ADDRESS FROM WHERE
MOV ES,CS:RH_SEG ; DEVICE STRATEGY PUT IT
MOV AL,ES:[BX]+2 ;GET FUNCTION BYTE
ROL AL,1 ;GET OFFSET INTO TABLE
LEA DI,FUNTAB ;GET ADDRESS OF FUNCTION TABLE
XOR AH,AH
ADD DI,AX
JMP WORD PTR[DI]
;
; THE FOLLOWING ENTRIES ARE NOT SUPPORTED BY THIS DEVICE
;
IOCTL_IN:
IOCTL_OUT:
ND_INPUT:
IN_STAT:
IN_FLUSH:
OUT_STAT:
OUT_FLUSH:
MEDIA_CHECK:
BUILD_BPB:
OUT_VERIFY:
STATUS DONE,ERROR,03 ;SET STATUS BYTE AS "ERROR-UNK COMMAND"
JMP EXIT
;
; INPUT = READ THE CLOCK CHIP
;
INPUT:
CALL IN_SAVE ;CALL THE INITIAL SAVE RTN
CALL READ_CLOCK ;READ IN THAT DATE/TIME
MOV BX,CS:RH_OFF ;RESTORE ES:BX AS REQ HDR PTR
MOV ES,CS:RH_SEG
STATUS DONE,NOERROR,0
JMP EXIT
;
; OUTPUT = SET TIME & DATE
;
OUTPUT:
CALL IN_SAVE ;CALL INITIAL SAVE ROUTINE
CALL SET_CLOCK ;SET TIME & DATE
call set_bios_counter ;also set bios time counter dmo
MOV BX,CS:RH_OFF ;RESTORE ES:BX AS REQ HDR PTR
MOV ES,CS:RH_SEG
STATUS DONE,NOERROR,0
JMP EXIT
;
; EVERYBODY'S EXIT
;
EXIT:
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POP ES
POP DS
RET
;
; INIT
;
INIT:
PUSH CS
POP AX ;CURRENT CS TO AX
; ADD AX,OFFSET INIT ;WRONG OFFSET ***FAS
MOV DX,OFFSET INIT ;CORRECT OFFSET ***FAS
; MOV ES:WORD PTR BR_ADDR_0[BX],0 ;WRONG ADD ***FAS
MOV ES:WORD PTR BR_ADDR_0[BX],DX ;CORRECT ADD ***FAS
MOV ES:BR_ADDR_1[BX],AX ;MAKE THAT THE BREAK ADDRESS
;
;CHECK VERIFY BYTE - HAS SOME OTHER SOFTWARE DIDDLED THE CLOCK?
;
MOV DX,CLOCK+VALID ;PORT FOR VERIFY RAM
IN AL,DX
CMP AL,VALID_CODE ;ARBITRARY VALIDATION CODE
JZ FINE
;
;RESET CHIP, CAN'T TRUST IT
;
MOV AL,0FFH ;RESET ALL REGISTERS
MOV DX,CLOCK+COUNTER_RESET ;
OUT DX,AL ;RESET ALL COUNTERS
INC DX ;RAM(LATCH) RESET ADDR
OUT DX,AL ;NOW RESET RAM
MOV AL,VALID_CODE
MOV DX,CLOCK+VALID ;NOW VALIDATE RAM
OUT DX,AL
FINE:
; dmo
; now - initialize bios ram counter dmo
; dmo
call read_chip ;time off chip dmo
call set_bios_counter ;setup bios timer dmo
STATUS DONE,NOERROR,0
JMP EXIT
CLK ENDP
CSEG ENDS
END BEGIN
ounter ;setup bios timer dmo
STATUS DONE,NOERROR,0
JMP EXIT
CLK ENDP
CSEG ENDS
END BEGIN